﻿namespace Rsdn.Janus.CoreServices.ObjectModel
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using BLToolkit.Data.Linq;
    using DataModel;
    using Extensibility;
    using SmartApp;

    public abstract class VirtualForumMessage : LinearTreeMsg
    {
        private readonly ISharedInfoService sharedInfoService;

        protected VirtualForumMessage(IServiceProvider provider)
            : base(provider)
        {
            this.sharedInfoService = provider.GetRequiredService<ISharedInfoService>();

        }

        public int UnreadCount
        {
            get
            {
                return RepliesUnread;
            }

            set
            {
                RepliesUnread = value;
            }
        }


        protected override void FillChildren()
        {
            // do nothing    
        }

        public void FillChildrenWithMessages()
        {
            Children = GetMessagesList();

            int unreadCount = 0;
            foreach (MsgBase msg in Children)
            {
                msg.EndMapping(null);
                if (msg.IsUnread)
                {
                    unreadCount++;
                }

                // Why read & unread is different fields?
                // msg.IsRead
            }

            Unread = unreadCount;

            //return msg;
        }

        protected abstract IQueryable<IForumMessage> GetMessages(IJanusDataContext db);

        /// <summary>
        /// Определяет нужно ли загружать все сообщения или использовать значение из установок.
        /// </summary>
        /// <value>
        /// 	<c>true</c> Если нужно всегда загружать все сообщения; иначе, <c>false</c>.
        /// </value>
        protected abstract bool IsLoadAllMessages { get; }

        public virtual void FillCounters()
        {
            using (IJanusDataContext db = ServiceProvider.CreateDBContext())
            {
                if (db.IsValid())
                {
                    IQueryable<IForumMessage> forumMessages = GetMessages(db);
                    RepliesCount = forumMessages.Count();
                    UnreadCount = forumMessages.Count(im => !im.IsRead);

                    #region SQL

                    #endregion
                }
            }
        }

        public virtual List<MsgBase> GetMessagesList()
        {
            List<MsgBase> ret = null;
            //bool loadAll = true;
            //SortType sort = xConfig.Instance.ForumSortCriteria;
            SortType sort = (SortType)this.sharedInfoService.GetEnumValue(SharedInfoKeys.ForumSortCriteria);

            using (var db = ServiceProvider.CreateDBContext())
            {
                IQueryable<IForumMessage> messages = GetMessages(db);

                messages = ForumDBHelper.AppendSortPredicate(messages, sort);
                IForumDisplayConfig forumDisplayConfig =
                    this.sharedInfoService.GetObjValue(SharedInfoKeys.ForumDisplayConfig) as IForumDisplayConfig;

                if (forumDisplayConfig != null)
                {
                    if (forumDisplayConfig.ShowUnreadThreadsOnly)
                    {
                        // messages = messages.Where(ti => !ti.Message.IsRead || ti.AnswersUnread > 0);
                    }
                    #region SQL
                    /*
                -  SQLite
                -- DECLARE @lastUpdateDateTime DateTime
                -- DECLARE @p1 Int32

                -- SET @lastUpdateDateTime = 31.05.2011 23:12:49
                -- SET @p1 = 95947

                SELECT
	                [m].[mid] as [ID],
	                [m].[tid] as [TopicID],
	                [m].[pid] as [ParentID],
	                [m].[gid] as [ForumID],
	                [m].[Subject],
	                [m].[dte] as [Date1],
	                [m].[uid] as [UserID],
	                [m].[uclass] as [UserClass],
	                [m].[UserNick],
	                [m].[Name],
	                [m].[article_id] as [ArticleId],
	                [m].[LastModerated],
	                [m].[Closed],
	                [m].[Message],
	                [m].[IsMarked],
	                [m].[IsRead],
	                [m].[ReadReplies]
                FROM
	                [messages] [m]
		                LEFT JOIN [messages] [t1] ON [m].[pid] = [t1].[mid]
                WHERE
	                [m].[dte] > @lastUpdateDateTime AND [t1].[uid] <> @p1
                ORDER BY
	                [m].[dte] DESC
                 */
                    #endregion

                    if (!(IsLoadAllMessages || forumDisplayConfig.MaxTopicsPerForum <= 0))
                    {
                        messages = messages.Take(forumDisplayConfig.MaxTopicsPerForum);
                    }
                }

                Table<IForumMessage> msgTable = db.Messages();
                ret = DataHelper.LoadMessages(ServiceProvider, messages, msgTable);
            }

            return ret;
        }

        protected ISharedInfoService SharedInfo
        {
            get { return sharedInfoService; }
        }

    }
}